package com.giacom.docx4j.plugin.impl;

import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

/**
 * 
 * Gerador de entidades
 * 
 * @author Sandro
 *
 */
public class EntityGenerator {
	
	public String generate(String name, List<EntityField> f) throws Exception {
		
		StringBuilder sb = new StringBuilder();
		
		sb.append("import javax.persistence.*;");
		sb.append("\nimport javax.validation.constraints.NotNull;");
		sb.append("\nimport java.io.*;");
		
		sb.append("\n\n");
		sb.append("@Entity");
		
		sb.append("\n");
		sb.append("@Table(name = \"").append(name).append("\")");
		
		sb.append("\n");
		sb.append("@TableGenerator(name=");
		sb.append("\"SEQ_" + name.toUpperCase() + "\"");
		sb.append(", allocationSize=1");
		sb.append(", table=\"" + "ID_GEN" + "\"");
		sb.append(", pkColumnName=\"" + "SEQ_NAME" + "\"");
		sb.append(", pkColumnValue=\"" + name.toUpperCase() + "_ID" + "\"");
		sb.append(", valueColumnName=\"" + "SEQ_COUNT" + "\")");
		
		sb.append("\n");
		sb.append("public class " + name + "  implements Serializable {");
		
		sb.append("\n\n");
		
		//ID da entidade
		sb.append("\t@Id");
		sb.append("\n\t");
		sb.append("@GeneratedValue(strategy = GenerationType.TABLE, generator = \"SEQ_" +  name.toUpperCase()  + "\")");
		sb.append("\n\t");
		sb.append("@NotNull");
		sb.append("\n\t");
		sb.append("private int id;");
	
		sb.append("\n");
		
		//demais campos
		for (EntityField field : f) {
			sb.append("\n\t");
			//annotations
			sb.append("@Column");
			if(field.getSize() != null && !field.getSize().isEmpty()){
				sb.append("(length="+field.getSize()+")");
			}
			if(field.isRequired()){
				sb.append("\n\t");
				sb.append("@NotNull");
			}
			sb.append("\n\t");
			sb.append("private ").append(getType(field)).append(" ");
			sb.append(field.getName()).append(";");
		}
	
		//getters and setters Id
		sb.append("\n");
		sb.append("\n\t");
		sb.append("public int getId(){");
		sb.append("\n\t\t");
		sb.append("return this.id;");
		sb.append("\n\t}");
		
		sb.append("\n");
		sb.append("\n\t");
		sb.append("public void setId(int id){");
		sb.append("\n\t\t");
		sb.append("this.id = id;");
		sb.append("\n\t}");
		
		
		//getters and setters demais campos
		for (EntityField field : f) {
			sb.append("\n");
			sb.append("\n\t");
			sb.append("public " + getType(field) + " get" +  StringUtils.capitalize(field.getName()) + "(){");
			sb.append("\n\t\t");
			sb.append("return this." + field.getName() + ";");
			sb.append("\n\t}");
			
			sb.append("\n");
			sb.append("\n\t");
			sb.append("public void set" + StringUtils.capitalize(field.getName()) + "(" + getType(field) + " " + field.getName() + "){");
			sb.append("\n\t\t");
			sb.append("this." + field.getName() + " =  " + field.getName() + ";");
			sb.append("\n\t}");
		}
		
		
		sb.append("\n\n");	
		sb.append("}");
		
		//System.out.println(sb.toString());
		
		String entityGen = "./gen/" + name + ".java";
		
		FileWriter w = new FileWriter("./gen/" + name + ".java");
		w.write(sb.toString());
		w.flush();
		w.close();
		
		return entityGen;
		
	}
	
	/**
	 * Recupera o tipo de variavel conforme informado no type
	 * @param f 
	 * @return
	 */
	private String getType(EntityField f) {

		switch (f.getType()) {
		case "S":
			return "String";
		case "N":
			return "Integer";
		case "D":
			return "Double";
		case "DT":
			return "Date";
		case "F":
			return "Float";
		case "B":
			return "byte[]";
			
			
		}
		
		
		return null;
	}

	public static void main(String[] args) {
		try {
			
			EntityField f = new EntityField();
			f.setName("nome");
			f.setDescription("descricao");
			f.setRequired(true);
			f.setSize("100");
			f.setType("S");
			
			List<EntityField> fl = new ArrayList<EntityField>();
			fl.add(f);
			
			new EntityGenerator().generate("Pessoa", fl);
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
